package com.sf.fy.uav.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sf.fy.uav.common.enums.ScenicSpotStatusEnum;
import com.sf.fy.uav.common.request.operate.PlacementPointReq;
import com.sf.fy.uav.common.request.operate.ScenicSpotReq;
import com.sf.fy.uav.common.response.operational.PlacementPointRes;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.RespJsonPageData;
import com.sf.fy.uav.common.utils.Rs;
import com.sf.fy.uav.common.enums.ScenicSpotStatusEnum;
import com.sf.fy.uav.entity.PlacementPoint;
import com.sf.fy.uav.mapper.PlacementPointMapper;
import com.sf.fy.uav.service.IPlacementPointService;
import com.sf.fy.uav.withdrawal.entity.ScenicSpot;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2023-12-07
 */
@Service
@RequiredArgsConstructor
public class PlacementPointServiceImpl extends ServiceImpl<PlacementPointMapper, PlacementPoint> implements IPlacementPointService {
    private final PlacementPointMapper placementPointMapper;
    private static final String LONGITUDE_AND_LATITUDE = "^[0-9]+(.[0-9]{1,8})?$";
    private static final String EXPRESS_FEE_CHECK = "^[0-9]+(.[0-9]{0,2})?$";

    private static final Integer CONST_NUM = 0;

    private static final Integer NAME_CHECK = 10;

    private static final String SCENIC_SPOT_ID = "";

    @Override
    public RespJsonPageData<PlacementPointRes> getPagePlacementPoint(PlacementPointReq placementPointReq) {
        if(StringUtils.isBlank(placementPointReq.getScenicSpotId())){
            throw new RuntimeException("景区id不能为空!");
        }
        LambdaQueryWrapper<PlacementPoint> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(placementPointReq.getName()) ,PlacementPoint::getName,placementPointReq.getName())
                .eq(!ObjectUtils.isEmpty(placementPointReq.getStatus()),PlacementPoint::getStatus,placementPointReq.getStatus())
                .eq(PlacementPoint::getScenicSpotId,placementPointReq.getScenicSpotId())
                .eq(PlacementPoint::getDeleted,false)
                .orderByDesc(PlacementPoint::getCreateTime);
        Page<PlacementPoint> placementPointPageList = placementPointMapper.selectPage(new Page<>(placementPointReq.getPage(), placementPointReq.getSize()),wrapper);
        List<PlacementPointRes> placementPointResList = BeanUtil.copyProperties(placementPointPageList.getRecords(), PlacementPointRes.class);
        if(!CollectionUtils.isEmpty(placementPointResList)){
            placementPointResList.forEach(placementPointRes ->{
                placementPointRes.setStatusName(ScenicSpotStatusEnum.getDesc(placementPointRes.getStatus()));
            });
        }
        return RespJsonPageData.success(placementPointResList,placementPointPageList.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> addPlacementPoint(PlacementPointReq placementPointReq) {
        batchVoidAnce(placementPointReq);
        Date date = new Date();
        PlacementPoint placementPoint = BeanUtil.copyProperties(placementPointReq, PlacementPoint.class);
        placementPoint.setCreateTime(date);
        placementPoint.setUpdateTime(date);
        placementPoint.setDeleted(false);
        int con = placementPointMapper.insert(placementPoint);
        if(con>CONST_NUM){
            return Rs.success(CONST_NUM);
        }else {
            return Rs.failed();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> updateById(PlacementPointReq placementPointReq) {
        if(StringUtils.isBlank(placementPointReq.getId())){
            throw new RuntimeException("投放点id不能为空");
        }
        batchVoidAnce(placementPointReq);
        PlacementPoint placementPoint = BeanUtil.copyProperties(placementPointReq, PlacementPoint.class);
        placementPoint.setUpdateTime(new Date());
        int updateCum = placementPointMapper.updateById(placementPoint);
        if(updateCum>CONST_NUM){
            return Rs.success(CONST_NUM);
        }else {
            return Rs.failed();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> deletedPlacementPoint(PlacementPointReq placementPointReq) {
        if(StringUtils.isBlank(placementPointReq.getId())){
            throw new RuntimeException("投放点id不能为空");
        }
        if(StringUtils.isBlank(placementPointReq.getProcessedBy())){
            throw new RuntimeException("操作人不能为空");
        }
        PlacementPoint placementPoint = BeanUtil.copyProperties(placementPointReq, PlacementPoint.class);
        placementPoint.setScenicSpotId(SCENIC_SPOT_ID);
        placementPoint.setUpdateTime(new Date());
        int updateCum = placementPointMapper.updateById(placementPoint);
        if(updateCum>CONST_NUM){
            return Rs.success(CONST_NUM);
        }else {
            return Rs.failed();
        }
    }

    private void batchVoidAnce(PlacementPointReq placementPointReq){
        if(StringUtils.isBlank(placementPointReq.getName())){
            throw new RuntimeException("投放点名称不能为空");
        }
        if(placementPointReq.getName().length()>NAME_CHECK){
            throw new RuntimeException("投放点名称长度不能超过10位");
        }
        if(ObjectUtils.isEmpty(placementPointReq.getLongitude())||placementPointReq.getLongitude().compareTo(BigDecimal.ZERO)<=CONST_NUM){
            throw new RuntimeException("经度不能为空,不能为零或负数");
        }
        if(ObjectUtils.isEmpty(placementPointReq.getLatitude())||placementPointReq.getLatitude().compareTo(BigDecimal.ZERO)<=CONST_NUM){
            throw new RuntimeException("纬度不能为空,不能为零或负数");
        }
        if(!placementPointReq.getLongitude().toString().matches(LONGITUDE_AND_LATITUDE)){
            throw new RuntimeException("经度只能是正数或者最大8位小数");
        }
        if(!placementPointReq.getLatitude().toString().matches(LONGITUDE_AND_LATITUDE)){
            throw new RuntimeException("纬度只能是正数或者最大8位小数");
        }
        if(ObjectUtils.isEmpty(placementPointReq.getExpressFee())||placementPointReq.getExpressFee().compareTo(BigDecimal.ZERO)<CONST_NUM){
            throw new RuntimeException("配送费不能为空,不能为负数");
        }
        if(!placementPointReq.getExpressFee().toString().matches(EXPRESS_FEE_CHECK)){
            throw new RuntimeException("配送费只能是正数或者最大2位小数");
        }
        if(ObjectUtils.isEmpty(placementPointReq.getStatus())){
            throw new RuntimeException("状态不能为空");
        }
        if(StringUtils.isBlank(placementPointReq.getProcessedBy())){
            throw new RuntimeException("处理人不能为空");
        }
    }
    @Override
    public PlacementPoint selectById(String id) {
        QueryWrapper<PlacementPoint> placementPointQueryWrapper = new QueryWrapper<>();
        placementPointQueryWrapper.eq("id", id);
        placementPointQueryWrapper.eq("status", ScenicSpotStatusEnum.NORMAL.getValue());
        placementPointQueryWrapper.eq("deleted", false);
        return placementPointMapper.selectOne(placementPointQueryWrapper);
    }
}
